package org.jawp.persistence;

import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;

public class OrderDAO {
	static private OrderDAO dao = null;
	private final DBCollection orderCollection;
	private int currentId;

	/*************************************
	 *			Constructor
	 * @throws MongoException 
	 * @throws UnknownHostException 
	 *************************************/

	private OrderDAO() throws UnknownHostException, MongoException { //TODO change to private, add a Singleton constructor
		// connect to mongoDB (ip and port number are optional)
		Mongo mongo = new Mongo();

		// get database from MongoDB,
		// if database doesn't exists, mongoDB will create it automatically
		DB db = mongo.getDB("JAWP_DB");

		// Get collection from MongoDB, database named "Orders"
		// if collection doesn't exists, mongoDB will create it automatically
		orderCollection = db.getCollection("Orders");

		// query the lastest id
		DBCursor cursor = orderCollection.find().sort(new BasicDBObject("id", -1)).limit(1);
		// get the result
		if(cursor.size() == 0)
			currentId = 0;
		else{
			DBObject result = cursor.next();
			currentId = ((Integer)result.get("id")).intValue() + 1;
		}
	}

	public static OrderDAO getOrderDAO() throws UnknownHostException, MongoException {
		if(dao == null){
			dao = new OrderDAO();
		}
		return dao;
	}

	/*************************************
	 *				Creation
	 *************************************/

	public Order createNewOrder(int customerId) {
		Order order = new Order(currentId, customerId);

		// create a document to store key and value
		BasicDBObject document = new BasicDBObject();
		document.put("id", currentId);
		document.put("customerId", customerId);

		// save it into collection
		orderCollection.insert(document);

		// increment current id
		currentId++;

		return order;
	}

	/*************************************
	 *				Getter
	 *************************************/

	public List<Order> getOrders() {		 
		// search query
		BasicDBObject searchQuery = new BasicDBObject();

		// query it
		DBCursor cursor = orderCollection.find(searchQuery);

		List<Order> orders = new LinkedList<Order>();
		while(cursor.hasNext()){
			DBObject object = cursor.next();
			orders.add(new Order((Integer)object.get("id"), (Integer)object.get("customerId")));
		}

		return orders;
	}

	public List<Order> getOrdersByCustomer(int customerId) {		 
		// search query
		BasicDBObject searchQuery = new BasicDBObject();

		// query it
		DBCursor cursor = orderCollection.find(searchQuery);
		searchQuery.put("customerId", customerId);

		List<Order> orders = new LinkedList<Order>();
		while(cursor.hasNext()){
			DBObject object = cursor.next();
			orders.add(new Order((Integer)object.get("id"), (Integer)object.get("customerId")));
		}

		return orders;
	}

	public Order getOrderById(int id) {		 
		// search query
		BasicDBObject searchQuery = new BasicDBObject();
		searchQuery.put("id", id);

		// query it
		DBObject object = orderCollection.findOne(searchQuery);

		if(object == null){
			return null;
		}

		return new Order(id, (Integer)object.get("customerId"));
	}

	/*************************************
	 *				Setter
	 *************************************/

	/*************************************
	 *				Deletion
	 *************************************/

	public void deleteOrder(int id) {

		BasicDBObject searchQuery = new BasicDBObject();
		searchQuery.put("id", id);

		orderCollection.remove(orderCollection.findOne(searchQuery));
	}

	public void deleteOrdersByCustomer(int customerId) {

		BasicDBObject searchQuery = new BasicDBObject();
		searchQuery.put("customerId", customerId);

		// query it
		DBCursor cursor = orderCollection.find(searchQuery);

		while(cursor.hasNext()){
			orderCollection.remove(cursor.next());
		}
	}
}
